package com.example.SpringRestApp.controller;


import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;

import com.example.SpringRestApp.beans.Campaign;
import com.example.SpringRestApp.beans.CampaignList;
import com.example.SpringRestApp.dao.CampaignRepo;
import com.example.SpringRestApp.exception.NotFoundException;

@Component("campaignsRestController")
@Controller
@RequestMapping("/campaigns")
public class CampaignsRestController {
	
	Logger log = Logger.getLogger(CampaignsRestController.class);
	
	@Autowired
	CampaignRepo campaignRepo;
	
	/*********************************************************
	 * 
	 * /campaigns
	 * 
	 *********************************************************/
	
	@RequestMapping(method=RequestMethod.GET)
	@ResponseBody
	public CampaignList getCampaignList() {
		log.info("getCampaignList()");
		return new CampaignList(campaignRepo.getCampaigns());
	}
	
	@RequestMapping(method=RequestMethod.PUT)
	@ResponseStatus(HttpStatus.OK)
	public void putCampaignList(@RequestBody CampaignList campaignList) {
		log.info("putCampaignList()");
		campaignRepo.replaceAll(campaignList.getCampaigns());
	}
	
	@RequestMapping(method=RequestMethod.POST)
	@ResponseStatus(HttpStatus.MOVED_PERMANENTLY)
	public void postCampaign(@RequestBody Campaign campaign,
			WebRequest request, HttpServletResponse response) {
		log.info("postCampaign(@RequestBody Campaign campaign, WebRequest request, HttpServletResponse response)");
		campaignRepo.addCampaign(campaign);
		response.setHeader("Location", request.getContextPath()+"/services/campaigns/"+campaign.getName());
	}
	
	@RequestMapping(method=RequestMethod.DELETE)
	@ResponseStatus(HttpStatus.OK)
	public void deleteAllCampaigns() {
		log.info("deleteAllCampaigns()");
		for(Campaign c : campaignRepo.getCampaigns()) {
			campaignRepo.removeCampaign(c.getName());
		}
	}
	
	/*********************************************************
	 * 
	 * /campaigns/{name}
	 * 
	 *********************************************************/
	
	@RequestMapping(value="/{name}", method=RequestMethod.GET)
	@ResponseBody
	public Campaign getCampaignByName(@PathVariable("name") String campaignName) throws NotFoundException {
		log.info("getCampaignByName(@PathVariable('name') String campaignName)");
		Campaign c = campaignRepo.getCampaign(campaignName);
		if(c == null) { throw new NotFoundException(); }
		return c;
	}
	
	@RequestMapping(value="/{name}", method=RequestMethod.PUT)
	@ResponseStatus(HttpStatus.OK)
	public void putCampaign(@PathVariable("name") String campaignName, @RequestBody Campaign campaign) {
		log.info("putCampaign(@PathVariable('name') String campaignName, @RequestBody Campaign campaign)");
		campaignRepo.addCampaign(campaign);
	}
	
	@RequestMapping(value="/{name}", method=RequestMethod.POST)
	@ResponseStatus(HttpStatus.OK)
	public void postCampaign(@PathVariable("name") String campaignName, @RequestBody Campaign campaign) {
		// In questo caso campaignName dovrebbe essere una collection
		// e campaign un elemento da aggiungere
	}
	
	@RequestMapping(value="/{name}", method=RequestMethod.DELETE)
	@ResponseStatus(HttpStatus.OK)
	public void deleteCampaign(@PathVariable("name") String campaignName) {
		log.info("deleteCampaign(@PathVariable('name') String campaignName)");
		campaignRepo.removeCampaign(campaignName);
	}
	
	/*********************************************************
	 * 
	 * Exception Handlers
	 * 
	 *********************************************************/
	
	@ExceptionHandler(NotFoundException.class)
	@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Campaign not found")
	public void handleNotFound(NotFoundException e) {
		log.error(e.getMessage(), e);
	}
	
	@ExceptionHandler(Exception.class)
	@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR, reason="Sorry!")
	public void handleException(Exception e) {
		log.error(e.getMessage(), e);
	}

}
